﻿using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using HtmlAgilityPack;

namespace Mvc.RazorTools.FontAwesome.CodeDesigner
{
	class Program
	{
		static void Main(string[] args)
		{
			Program.Process();
		}

		public static void Process()
		{
			// ***
			// *** Read the code template
			// ***
			string definitionsTemplate = Properties.Resources.CodeTemplate;
			string unitTestTemplate = Properties.Resources.UnitTestTemplate;
			string unitTestClassTemplate = Properties.Resources.UnitTestClassTemplate;

			// ***
			// *** Get the cheat sheet from the Font Awesome web site. This document
			// *** will be used to get the version and the current list of icons
			// ***
			HtmlWeb htmlWeb = new HtmlWeb();
			HtmlDocument document = htmlWeb.Load("http://fontawesome.io/cheatsheet/");

			// ***
			// *** Get the version from the document
			// ***
			string version = "unknown";
			var h2nodes = document.DocumentNode.Descendants("h2");

			if (h2nodes.First().InnerText.Contains("Every Font Awesome "))
			{
				string text = h2nodes.First().InnerText;
				int start = text.IndexOf("Every Font Awesome ") + "Every Font Awesome ".Length;
				int finish = text.IndexOf(" Icon,");

				// ***
				// *** Get the version
				// ***
				version = text.Substring(start, finish - start);
				definitionsTemplate = definitionsTemplate.Replace("%_Version_%", version);
			}

			// ***
			// *** Get a list of all <i> tags
			// ***
			var nodes = document.DocumentNode.Descendants("i");
			List<Icon> icons = new List<Icon>();

			// ***
			// *** Load the items into a list of objects of type Icon
			// ***
			foreach (var node in nodes)
			{
				// ***
				// *** Only use the <i> tags that have inner text
				// ***
				if (!string.IsNullOrEmpty(node.InnerText))
				{
					string iconCode = node.InnerText.Substring(3, 4);
					int code = int.Parse(iconCode, NumberStyles.HexNumber);
					HtmlNode next = node.NextSibling;
					string id = next.InnerText.Replace("\n", string.Empty).Trim();
					string name = ConvertName(id);
					bool alias = node.NextSibling.NextSibling.InnerText.Equals("(alias)");

					icons.Add(new Icon() { Name = name, Id = id, Unicode = code, HexCode = node.InnerText, IsAlias = alias });
				}
			}

			// ***
			// *** Build the Initialization List
			// ***
			StringBuilder predefinedList = new StringBuilder();
			StringBuilder initList = new StringBuilder();
			StringBuilder unitTests = new StringBuilder();

			foreach (var icon in icons)
			{
				initList.AppendLine(string.Format("\t\t\t\t\t_allItems.Add(\"{0}\", FontAwesomeIcon.Create(\"{1}\", {2}, \"{0}\", true, {3}));", icon.Name, icon.Id, icon.Unicode, icon.IsAlias.ToString().ToLower()));

				predefinedList.AppendLine("\t\t/// <summary>");
				predefinedList.AppendLine(string.Format("\t\t/// Class = {0}, Unicode = 0x{1}", icon.Id, icon.Unicode.ToString("X4").ToLower()));
				predefinedList.AppendLine("\t\t/// </summary>");
				predefinedList.AppendLine(string.Format("\t\tpublic static FontAwesomeIcon {0} = FontAwesomeIconSet.AllItems[\"{0}\"];", icon.Name));
				predefinedList.AppendLine(string.Empty);

				string unitTest = unitTestTemplate.Replace("%_Name_%", icon.Name);
				unitTest = unitTest.Replace("%_Id_%", icon.Id);
				unitTest = unitTest.Replace("%_Unicode_%", icon.Unicode.ToString());
				unitTest = unitTest.Replace("%_UnicodeHex_%", icon.Unicode.ToString("X4").ToLower());
				unitTests.AppendLine(unitTest);
				unitTests.AppendLine(string.Empty);
			}

			// ***
			// *** Add the list to the template by replacing the
			// *** %_Init_List_% text
			// ***
			definitionsTemplate = definitionsTemplate.Replace("%_Init_List_%", initList.ToString());

			// ***
			// *** Add the list to the template by replacing the
			// *** %_Predefined_List_% text
			// ***
			definitionsTemplate = definitionsTemplate.Replace("%_Predefined_List_%", predefinedList.ToString());

			// ***
			// *** Add the icon count
			// ***
			definitionsTemplate = definitionsTemplate.Replace("%_Icon_Count_%", icons.Count.ToString());



			// ***
			// *** Add the list to the template by replacing the
			// *** %_Tests_% text
			// ***
			unitTestClassTemplate = unitTestClassTemplate.Replace("%_Tests_%", unitTests.ToString());

			// ***
			// *** Write the output files
			// ***
			File.WriteAllText("FontAwesomeIconSet.cs", definitionsTemplate);
			File.WriteAllText("PredefinedFontAwesomeIconTests.cs", unitTestClassTemplate);
		}

		public static string ConvertName(string id)
		{
			string returnValue = string.Empty;

			CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
			TextInfo textInfo = cultureInfo.TextInfo;
			returnValue = textInfo.ToTitleCase(id.Substring(3, id.Length - 3)).Replace("-", string.Empty);

			return returnValue;
		}
	}
}
